#include"utils.h"

int SOCK_CREATE(int type,int protocol) {
    int lfd = socket(AF_INET,type,protocol);
    if(lfd<0){
        perror("socket create failed");
        return -1;
    }
    return lfd;
}

int SOCK_BIND(int socketfd,const char* ipstr,int port) {
    struct sockaddr_in addr;
    addr.sin_port = htons(port);
    addr.sin_family = AF_INET;
    inet_pton(AF_INET,ipstr,&addr.sin_addr);
    int ret = bind(socketfd,(struct sockaddr*)&addr,sizeof(addr));
    if(ret<0) {
        perror("bind error");
        close(socketfd);
        return -1;
    }
    return ret;
}
int SOCK_REUSE(int socketfd){
  int opt=1;
  int ret = setsockopt(socketfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
  if (ret<0) {
    perror("setsocket failed;");
    close(socketfd);
    return -1;
  }
  return ret;
}
int SOCK_CONN(int socketfd,const char* ipstr,int port) {
    struct sockaddr_in addr;
    addr.sin_port = htons(port);
    addr.sin_family = AF_INET;
    inet_pton(AF_INET,ipstr,&addr.sin_addr);
    int ret = connect(socketfd,(struct sockaddr*)&addr,sizeof(addr));
    if(ret<0) {
        perror("connect error");
        close(socketfd);
        return -1;
    }
    return ret;
}
int SOCK_LISTEN(int socketfd,int backlog) {
    int ret = listen(socketfd,backlog);
    if(ret<0) {
        perror("listend failed");
        close(socketfd);
        return -1;
    }
    return ret;
}
int SOCK_ACCEPT(int socketfd,struct sockaddr* addr,socklen_t * len) {
    int ret = accept(socketfd,addr,len);
    if(ret<0) {
        perror("accept failed");
        close(socketfd);
        return -1;
    }
    return ret;

}
ssize_t Read(int fd,void * buf,ssize_t nbytes) {
    ssize_t n;
AGAIN:
    if((n=read(fd,buf,nbytes))<0) {
        if(errno==EINTR)
        goto AGAIN;
        else{
            perror("read failed");
            return -1;
        } 
    }
    return n;
}
void SETNOBLK(int socketfd){

    if(fcntl(socketfd,F_SETFL,fcntl(socketfd,F_GETFL,0)|O_NONBLOCK)==-1){
        return ;
    }
    return;
}
ssize_t Readn(int fd,void * buf,ssize_t nsum) {
    ssize_t nleft = nsum;
    ssize_t nread = 0;
    char *ptr = (char*)buf;
    while(nleft>0) {
        if((nread=read(fd,ptr,nleft))<0){
            if(errno==EINTR) nread=0;
            else{
                perror("write failed");
                return -1;
            }
        }else if(nread==0) break;
        nleft -=nread;
        ptr +=nread;
    }
    return nsum -nleft;
}

ssize_t Write(int fd,void *buf,ssize_t nbytes) {
    ssize_t n;
    AGAIN:
        if((n=write(fd,buf,nbytes))<0){
            if(errno==EINTR)
            goto AGAIN;
            else{
                perror("write failed");
                return -1;
            }
        }
    return n;
}

ssize_t Writen(int fd,void *buf,ssize_t nsum) {
    ssize_t nleft=nsum;
    ssize_t nwrite=0;
    char *ptr=(char*)buf;
    while(nleft>0){
        if((nwrite=write(fd,buf,nleft))<=0){
            if(errno==EINTR) nwrite=0;
            else{
                perror("write failed");
                close(fd);
                return -1;
            }
        }
        nleft -=nwrite;
        ptr +=nwrite;
    }
    return nsum-nleft;
}
